#include "sysconfig.h"
#include "Configuration.h"
#include "disk.h"
#include "sound.h"

CConfiguration g_curr_conf = CConfiguration();
CConfiguration g_changed_conf = CConfiguration();
CConfiguration g_work_conf = CConfiguration();

bool record_sound = false;

// #define ASSERT_ON_COMPARE ASSERT(FALSE)
#define ASSERT_ON_COMPARE

#define CONF_CMP(x) \
    if (x != right.x) \
    { \
        ASSERT_ON_COMPARE; \
        return false; \
    }

#define CONF_CMP_ARR(x, n) \
    for (int i_ = 0; i_ < n; i_++) \
        if (x[i_] != right.x[i_]) \
        { \
            ASSERT_ON_COMPARE; \
            return false; \
        }

#define CONF_COMP_DELTA(x, n) \
    if (abs(x - right.x) > n) \
    { \
        ASSERT_ON_COMPARE; \
        return false; \
    }

CConfiguration::CConfiguration ()
{
    Version = 0;
    use_serial = false;
    serial_demand = false;
    serial_hwctsrts = false;
    serial_direct = false;
    parallel_matrix_emulation = 0;
    parallel_postscript_emulation = false;
    parallel_postscript_detection = false;
    parallel_autoflush_time = 0;
    socket_emu = false;

    keyboard_lang = KBD_LANG_US;

    sound_produce = true;
    sound_maxbsiz = 0;
    sound_interpol = SOUND_INTERPOLATION_NONE;
    sound_filter = FILTER_SOUND_OFF;
    sound_filter_type = FILTER_SOUND_TYPE_A500;
    sound_volume = 0;

    jit_no_flags = false;
    jit_fpu = false;
    jit_fpu_more_compatible = false;
    jit_hard_flush = false;
    jit_const_jump = false;
    jit_cache_size = 0;
    memset(&jit_optcount, 0, sizeof(int) * 10);

    gfx_display = 0;
    gfx_framerate = 0;

    memset(&gfx_size_win, 0, sizeof(wh));
    memset(&gfx_size_fs, 0, sizeof(wh));
    memset(&gfx_size, 0, sizeof(wh));

    gfx_scandoubler = false;
    gfx_refreshrate = 0;
    gfx_avsync = 0;
    gfx_pvsync = 0;
    gfx_avsyncmode = 0;
    gfx_pvsyncmode = 0;
    gfx_resolution = 0;
    gfx_vresolution = 0;
    gfx_lores_mode = 0;
    gfx_scanlines = 0;
    gfx_afullscreen = GFX_WINDOW;
    gfx_pfullscreen = GFX_WINDOW;
    gfx_xcenter = 0;
    gfx_ycenter = 0;
    gfx_luminance = 0;
    gfx_contrast = 0;
    gfx_gamma = 0;
    gfx_blackerthanblack = false;
    gfx_backbuffers = 0;
    gfx_color_mode = 1;

    gfx_filter = 0;
    gfx_filter_zoom_mult = 0;
    gfx_filter_keep_aspect = true;
    gfx_filter_aspect = 1;
    gfx_filter_autoscale = 0;

    immediate_blits = false;
    chipset_mask = 0;
    ntscmode = false;
    genlock = false;
    chipset_refreshrate = 0;
    collision_level = 0;
    leds_on_screen = 0;
    memset(&keyboard_leds, 0, sizeof(int) * 3);
    keyboard_leds_in_use = false;
    scsi = 0;
    sana2 = false;
    uaeserial = false;
    cpu_idle = 0;
    cpu_cycle_exact = false;
    cpu_clock_multiplier = 0;
    cpu_frequency = 0;
    blitter_cycle_exact = false;
    floppy_speed = 0;
    floppy_write_length = 0;
    floppy_random_bits_min = 1;
    floppy_random_bits_max = 3;
    tod_hack = false;
    turbo_emulation = 0;

    cs_compatible = 0;
    cs_ciaatod = 0;
    cs_rtc = 0;
    cs_ksmirror_e0 = false;
    cs_ksmirror_a8 = false;
    cs_ciaoverlay = false;
    cs_cd32cd = false;
    cs_cd32c2p = false;
    cs_cd32nvram = false;
    cs_cdtvcd = false;
    cs_cdtvram = false;
    cs_cdtvcard = 0;
    cs_ide = 0;
    cs_pcmcia = false;
    cs_a1000ram = false;
    cs_fatgaryrev = 0;
    cs_ramseyrev = 0;
    cs_mbdmac = 0;
    cs_cdtvscsi = false;
    cs_a2091 = false;
    cs_a4091 = false;
    cs_df0idhw = false;
    cs_slowmemisfast = false;
    cs_resetwarning = false;
    cs_denisenoehb = false;
    cs_dipagnus = false;
    cs_agnusbltbusybug = false;

    cart_internal = 0;

    inprec_autoplay = false;

    m68k_speed = 0;
    cpu_model = 0;
    mmu_model = 0;
    cpu060_revision = 0;
    fpu_model = 0;
    fpu_revision = 0;
    cpu_compatible = false;
    address_space_24 = false;
    picasso96_nocustom = false;
    picasso96_modeflags = 0;

    z3fastmem_size = 0;
    fastmem_size = 0;
    chipmem_size = 0;
    slowmem_size = 0;
    mbresmem_low_size = 0;
    mbresmem_high_size = 0;
    gfx_mem_size = 0;

    filesys_no_uaefsdb = false;
    filesys_custom_uaefsdb = false;
    uae_hide = 0;

    mountitems = 0;

    floppy_sound_volume = 0;

    win32_middle_mouse = false;
    win32_logfile = false;
    win32_alwaysontop = false;
    win32_powersavedisabled = false;
    win32_minimize_inactive = false;
    win32_statusbar = 0;

    win32_active_priority = 0;
    win32_inactive_priority = 0;
    win32_inactive_pause = false;
    win32_inactive_nosound = false;
    win32_iconified_priority = 0;
    win32_iconified_pause = false;
    win32_iconified_nosound = false;

    win32_rtgmatchdepth = false;
    win32_rtgscaleifsmall = false;
    win32_rtgallowscaling = false;
    win32_rtgscaleaspectratio = 0;
    win32_rtgvblankrate = 0;
    win32_borderless = false;
    win32_ctrl_F11_is_quit = false;
    win32_automount_removable = false;
    win32_automount_drives = false;
    win32_automount_cddrives = false;
    win32_automount_netdrives = false;
    win32_automount_removabledrives = false;
    win32_midioutdev = 0;
    win32_midiindev = 0;
    win32_uaescsimode = 0;
    win32_samplersoundcard = 0;
    win32_norecyclebin = false;
    win32_specialkey = 0;
    win32_guikey = 0;
    win32_kbledmode = 0;

    statecapturerate = 0;
    statecapturebuffersize = 0;

    input_selected_setting = 0;
    input_joymouse_multiplier = 0;
    input_joymouse_deadzone = 0;
    input_joystick_deadzone = 0;
    input_joymouse_speed = 0;
    input_analog_joystick_mult = 0;
    input_analog_joystick_offset = 0;
    input_autofire_linecnt = 0;
    input_mouse_speed = 0;
    input_virtual_mouse = false;
    input_magic_mouse = false;
    input_magic_mouse_cursor = 0;

    dongle = 0;
    input_contact_bounce = 0;
}

void CConfiguration::clear()
{
    *this = CConfiguration();
}

bool CConfiguration::operator != (const CConfiguration& right) const
{
    return !operator == (right);
}

bool CConfiguration::operator == (const CConfiguration& right) const
{
    CONF_CMP(Description);
    CONF_CMP(AdditionalInformation);
    CONF_CMP(config_hardware_path);
    CONF_CMP(config_host_path);

    CONF_CMP(use_serial);
    CONF_CMP(serial_demand);
    CONF_CMP(serial_hwctsrts);
    CONF_CMP(serial_direct);
    CONF_CMP(parallel_matrix_emulation);
    CONF_CMP(parallel_postscript_emulation);
    CONF_CMP(parallel_postscript_detection);
    CONF_CMP(parallel_autoflush_time);
    CONF_CMP(ghostscript_parameters);
    CONF_CMP(socket_emu);
    CONF_CMP(keyboard_lang);
    CONF_CMP(sound_produce);
    CONF_CMP(sound_maxbsiz);
    CONF_CMP(sound_interpol);
    CONF_CMP(sound_filter);
    CONF_CMP(sound_filter_type);
    CONF_CMP(sound_volume);
    CONF_CMP(jit_no_flags);
    CONF_CMP(jit_fpu);
    CONF_CMP(jit_fpu_more_compatible);
    CONF_CMP(jit_hard_flush);
    CONF_CMP(jit_const_jump);
    CONF_CMP(jit_cache_size);
    CONF_CMP(gfx_display);
    CONF_CMP(gfx_display_name);
    CONF_CMP(gfx_framerate);
    CONF_CMP(gfx_size_win);
    CONF_CMP(gfx_size_fs);
    CONF_CMP(gfx_scandoubler);
    CONF_CMP(gfx_refreshrate);
    CONF_CMP(gfx_avsync);
    CONF_CMP(gfx_pvsync);
    CONF_CMP(gfx_avsyncmode);
    CONF_CMP(gfx_pvsyncmode);
    CONF_CMP(gfx_resolution);
    CONF_CMP(gfx_vresolution);
    CONF_CMP(gfx_lores_mode);
    CONF_CMP(gfx_scanlines);
    CONF_CMP(gfx_afullscreen);
    CONF_CMP(gfx_pfullscreen);
    CONF_CMP(gfx_xcenter);
    CONF_CMP(gfx_ycenter);
    CONF_COMP_DELTA(gfx_luminance, 1);
    CONF_COMP_DELTA(gfx_contrast, 1);
    CONF_COMP_DELTA(gfx_gamma, 1);
    CONF_CMP(gfx_blackerthanblack);
    CONF_CMP(gfx_backbuffers);
    CONF_CMP(gfx_color_mode);
    CONF_CMP(gfx_filter);
    CONF_CMP(gfx_filtershader);
    CONF_CMP(gfx_filter_zoom_mult);

    CONF_CMP(gfx_filter_keep_aspect);
    CONF_CMP(gfx_filter_aspect);
    CONF_CMP(gfx_filter_autoscale);
    CONF_CMP(immediate_blits);
    CONF_CMP(chipset_mask);
    CONF_CMP(ntscmode);
    CONF_CMP(genlock);
    CONF_CMP(chipset_refreshrate);
    CONF_CMP(cr_selected);
    CONF_CMP_ARR(cr, MAX_CHIPSET_REFRESH + 2);
    CONF_CMP(collision_level);
    CONF_CMP(leds_on_screen);
    CONF_CMP_ARR(keyboard_leds, 3);
    CONF_CMP(keyboard_leds_in_use);
    CONF_CMP(scsi);
    CONF_CMP(sana2);
    CONF_CMP(uaeserial);
    CONF_CMP(cpu_idle);
    CONF_CMP(cpu_cycle_exact);
    CONF_CMP(cpu_clock_multiplier);
    CONF_CMP(cpu_frequency);
    CONF_CMP(blitter_cycle_exact);
    CONF_CMP(floppy_speed);
    CONF_CMP(floppy_write_length);
    CONF_CMP(floppy_random_bits_min);
    CONF_CMP(floppy_random_bits_max);
    CONF_CMP(tod_hack);
    CONF_CMP(turbo_emulation);
    CONF_CMP(cs_compatible);
    CONF_CMP(cs_ciaatod);
    CONF_CMP(cs_rtc);
    CONF_CMP(cs_ksmirror_e0);
    CONF_CMP(cs_ksmirror_a8);
    CONF_CMP(cs_ciaoverlay);
    CONF_CMP(cs_cd32cd);
    CONF_CMP(cs_cd32c2p);
    CONF_CMP(cs_cd32nvram);
    CONF_CMP(cs_cdtvcd);
    CONF_CMP(cs_cdtvram);
    CONF_CMP(cs_cdtvcard);
    CONF_CMP(cs_ide);
    CONF_CMP(cs_pcmcia);
    CONF_CMP(cs_a1000ram);
    CONF_CMP(cs_fatgaryrev);
    CONF_CMP(cs_ramseyrev);
    CONF_CMP(cs_mbdmac);
    CONF_CMP(cs_cdtvscsi);
    CONF_CMP(cs_a2091);
    CONF_CMP(cs_a4091);
    CONF_CMP(cs_df0idhw);
    CONF_CMP(cs_slowmemisfast);
    CONF_CMP(cs_resetwarning);
    CONF_CMP(cs_denisenoehb);
    CONF_CMP(cs_dipagnus);
    CONF_CMP(cs_agnusbltbusybug);
    CONF_CMP(romfile);
    CONF_CMP(romextfile);
    CONF_CMP(flashfile);
    CONF_CMP(cartfile);
    CONF_CMP(cart_internal);
    CONF_CMP(prtname);
    CONF_CMP(sername);
    CONF_CMP(a2065name);
    CONF_CMP(inprecfile);
    CONF_CMP(inprec_autoplay);
    CONF_CMP(m68k_speed);
    CONF_CMP(cpu_model);
    CONF_CMP(mmu_model);
    CONF_CMP(cpu060_revision);
    CONF_CMP(fpu_model);
    CONF_CMP(fpu_revision);
    CONF_CMP(cpu_compatible);
    CONF_CMP(address_space_24);
    CONF_CMP(picasso96_nocustom);
    CONF_CMP(picasso96_modeflags);
    CONF_CMP(z3fastmem_size);
    CONF_CMP(fastmem_size);
    CONF_CMP(chipmem_size);
    CONF_CMP(slowmem_size);
    CONF_CMP(mbresmem_low_size);
    CONF_CMP(mbresmem_high_size);
    CONF_CMP(gfx_mem_size);
    CONF_CMP(filesys_no_uaefsdb);
    CONF_CMP(filesys_custom_uaefsdb);
    CONF_CMP(uae_hide);
    CONF_CMP(floppy_sound_volume);
    CONF_CMP(win32_middle_mouse);
    CONF_CMP(win32_logfile);
    CONF_CMP(win32_alwaysontop);
    CONF_CMP(win32_powersavedisabled);
    CONF_CMP(win32_minimize_inactive);
    CONF_CMP(win32_statusbar);
    CONF_CMP(win32_active_priority);
    CONF_CMP(win32_inactive_priority);
    CONF_CMP(win32_inactive_pause);
    CONF_CMP(win32_inactive_nosound);
    CONF_CMP(win32_iconified_priority);
    CONF_CMP(win32_iconified_pause);
    CONF_CMP(win32_iconified_nosound);
    CONF_CMP(win32_rtgmatchdepth);
    CONF_CMP(win32_rtgscaleifsmall);
    CONF_CMP(win32_rtgallowscaling);
    CONF_CMP(win32_rtgscaleaspectratio);
    CONF_CMP(win32_rtgvblankrate);
    CONF_CMP(win32_borderless);
    CONF_CMP(win32_ctrl_F11_is_quit);
    CONF_CMP(win32_automount_removable);
    CONF_CMP(win32_automount_drives);
    CONF_CMP(win32_automount_cddrives);
    CONF_CMP(win32_automount_netdrives);
    CONF_CMP(win32_automount_removabledrives);
    CONF_CMP(win32_midioutdev);
    CONF_CMP(win32_midiindev);
    CONF_CMP(win32_uaescsimode);
    CONF_CMP(win32_samplersoundcard);
    CONF_CMP(win32_norecyclebin);
    CONF_CMP(win32_specialkey);
    CONF_CMP(win32_guikey);
    CONF_CMP(win32_kbledmode);
    CONF_CMP(statecapturerate);
    CONF_CMP(statecapturebuffersize);
    CONF_CMP(input_selected_setting);
    CONF_CMP(input_joymouse_multiplier);
    CONF_CMP(input_joymouse_deadzone);
    CONF_CMP(input_joystick_deadzone);
    CONF_CMP(input_joymouse_speed);
    CONF_CMP(input_analog_joystick_mult);
    CONF_CMP(input_analog_joystick_offset);
    CONF_CMP(input_autofire_linecnt);
    CONF_CMP(input_mouse_speed);
    CONF_CMP(input_virtual_mouse);
    CONF_CMP(input_magic_mouse);
    CONF_CMP(input_magic_mouse_cursor);
    CONF_CMP(dongle);
    CONF_CMP(input_contact_bounce);

    CONF_CMP_ARR(cdslots, MAX_TOTAL_SCSI_DEVICES);

    CONF_CMP(mountitems);
    CONF_CMP_ARR(mounted_devices, mountitems);

    CONF_CMP_ARR(floppies, 4);

    CONF_CMP_ARR(dfxlist, MAX_SPARE_DRIVES);
    CONF_CMP_ARR(jit_optcount, 10);

    CONF_CMP_ARR(jports, MAX_JPORTS);

    /*for (int i=0; i<MAX_INPUT_SETTINGS; i++)
       {
        CONF_CMP_ARR(joystick_settings[i], MAX_INPUT_DEVICES);
        CONF_CMP_ARR(mouse_settings[i], MAX_INPUT_DEVICES);
        CONF_CMP_ARR(keyboard_settings[i], MAX_INPUT_DEVICES);
       }*/

    return true;
}

void CConfiguration::setfloppycount(int a_count, int a_dfxtype /*= DRV_35_DD*/)
{
    for (int i = 0; i < 4; i++)
        floppies[i].dfxtype = (i < a_count) ? a_dfxtype : DRV_NONE;
}